package li.brauch.semesterarbeit.radio.controller;

import java.net.MalformedURLException;
import java.net.URL;

import li.brauch.semesterarbeit.radio.IRadio;
import li.brauch.semesterarbeit.radio.RadioPlugin;
import li.brauch.semesterarbeit.radio.model.StationTuneModel;
import li.brauch.semesterarbeit.radio.model.StationTuneResultModel;
import li.brauch.semesterarbeit.radio.model.Track;
import li.brauch.semesterarbeit.radio.sound.MP3Player;
import li.brauch.semesterarbeit.radio.views.Message;
import li.brauch.semesterarbeit.radio.views.RadioViewPart;

import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;


public abstract class RadioController implements Transition {
	
	protected Track currentTrack = null;
	
	public final static RadioController INIT = new RadioController() {
		
		public void reset(RadioViewPart viewPart) {
			
			IRadio radio = viewPart.getRadio();
			if (radio != null) {
				
				viewPart.getPlayer().stop();
				
				String[] types = radio.getStationTypes();		
				viewPart.getTunerPanel().setStationTypes(types);				
				
				// try to login
				login(viewPart);
			} else {
				viewPart.getTunerPanel().showMessage(Message.ERROR, "No radio was selected. Please choose one in <a>preference</a> page");
			}
		}
		
		public void login(RadioViewPart viewPart) {
			
			IRadio radio = viewPart.getRadio();
			if (radio != null) {
				try {
					radio.login();
				
					viewPart.setState(TUNING);
					viewPart.getTunerPanel().hideMessage();
					viewPart.getTunerPanel().setEnabled(true);
					viewPart.showTunerPanel();
					
				} catch (Exception e) {
					viewPart.getTunerPanel().showMessage(Message.WARNING, e.getMessage());
					viewPart.getTunerPanel().clearInput();
					viewPart.showTunerPanel();
				}
			} else {
				viewPart.getTunerPanel().showMessage(Message.ERROR, "No radio was selected. Please choose one in <a>preference</a> page");
			}
		};
	};
	
	public final static RadioController TUNING = new RadioController() {
		
		public void reset(RadioViewPart viewPart) {
			// Redirect
			INIT.reset(viewPart);
		};
		
		public void tune(RadioViewPart viewPart) {
			
			IRadio radio = viewPart.getRadio();
			
			StationTuneModel tuneModel = viewPart.getStationTuneModel();
			StationTuneResultModel resultModel;
			
			try {
				resultModel = radio.tuneStation(tuneModel);
				if (resultModel.isEmpty()) {
					
					viewPart.getTunerPanel().showMessage(Message.WARNING, "Station tuning failed. No station found.");
					
				} else if (resultModel.isUnique()) {				
					
					viewPart.setState(PLAYING);
					viewPart.showPlayerPanel();
					
					// Redirect
					PLAYING.play(viewPart);
					
				} else {
					
					viewPart.setState(SELECTING);
					viewPart.showSelectPanel();
					viewPart.getSelectPanel().setItems(resultModel.getResults());
				}
			} catch (Exception e) {
				viewPart.getTunerPanel().showMessage(Message.ERROR, "Error: " + e.getMessage());
			}
			
			
		};
	};
	
	public final static RadioController SELECTING = new RadioController() {
		
		public void tune(RadioViewPart viewPart) {
			
			viewPart.setState(TUNING);
			
			// redirect
			TUNING.tune(viewPart);		
		};
		
		public void reset(RadioViewPart viewPart) {
			// Redirect
			INIT.reset(viewPart);
		};
	};	
	
	public final static RadioController PLAYING = new RadioController() {
		
		public void play(RadioViewPart viewPart) {
			
			IRadio radio = viewPart.getRadio();
			try {
				currentTrack = radio.getNextTrack();
				viewPart.getPlayerPanel().setTrack(currentTrack);
				viewPart.getPlayer().play(currentTrack.getLocation());
				
			} catch (Exception e) {
				viewPart.setState(TUNING);	
				viewPart.showTunerPanel();
				viewPart.getTunerPanel().showMessage(Message.ERROR, e.getMessage());					
			}
		}
		
		public void skip(RadioViewPart viewPart) {
			viewPart.getPlayer().stop();
			PLAYING.play(viewPart);
		};
		
		public void stop(RadioViewPart viewPart) {
			viewPart.getPlayer().stop();
			viewPart.setState(TUNING);
			viewPart.showTunerPanel();
			viewPart.getTunerPanel().hideMessage();
		};
		
		public void pause(RadioViewPart viewPart) {
			viewPart.getPlayer().pause(true);
		};
		
		public void resume(RadioViewPart viewPart) {
			viewPart.getPlayer().pause(false);
		};
		
		public void buy(RadioViewPart viewPart) { 
		
			String url = RadioPlugin.getDefault().getPreferenceStore().getString("shopURL");
			url = url.replace("${artist}", currentTrack.getArtist());
			url = url.replace("${album}", currentTrack.getAlbum());
			
			try {				
				PlatformUI.getWorkbench().getBrowserSupport().createBrowser("myId").openURL(new URL(url)); 
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (PartInitException e) {
				
			}
		};
		
		public void reset(RadioViewPart viewPart) {
			// Redirect
			INIT.reset(viewPart);
		};
		
		public void love(RadioViewPart viewPart) {
			IRadio radio = viewPart.getRadio();
			try {
				radio.loveTrack();
			} catch (Exception e) {
				viewPart.showErrorMessageBox(e.getMessage());
			}
		};
		
		public void ban(RadioViewPart viewPart) { 
			IRadio radio = viewPart.getRadio();
			try {
				radio.banTrack();
			} catch (Exception e) {
				viewPart.showErrorMessageBox(e.getMessage());
			}
		};
		
	};
	
	public final static RadioController PAUSED = new RadioController() {
		
		public void resume(RadioViewPart viewPart) {
			MP3Player player = viewPart.getPlayer();
			player.pause(false);
			viewPart.setState(PLAYING);
		};
		
		public void love(RadioViewPart viewPart) {
			// Redirect
			PLAYING.love(viewPart);
		};
		
		public void ban(RadioViewPart viewPart) { 
			// Redirect
			PLAYING.ban(viewPart);
		};
		
		public void buy(RadioViewPart viewPart) {
			// Redirect
			PLAYING.ban(viewPart);
		};
		
		public void reset(RadioViewPart viewPart) {
			// Redirect
			INIT.reset(viewPart);
		};
		
		
	};
	
	private RadioController() {
		
	}
	
	public void login(RadioViewPart viewPart) {}
	public void tune(RadioViewPart viewPart) {}
	public void play(RadioViewPart viewPart) {}
	public void resume(RadioViewPart viewPart) {}
	public void pause(RadioViewPart viewPart) {}
	public void stop(RadioViewPart viewPart) {}
	public void volume(RadioViewPart viewPart) {}
	public void skip(RadioViewPart viewPart) {}
	public void ban(RadioViewPart viewPart) {}
	public void love(RadioViewPart viewPart) {}	
	public void buy(RadioViewPart viewPart) {}
	public void reset(RadioViewPart viewPart) {}
}